﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Flagwind.Data
{
	public class JoinEntity
	{
		private Command _mainCommand;
		private string _joinType;
		private IEntity _joinedEntity;

		public string JoinedString
		{
			get;
			private set;
		}

		public string LeftString
		{
			get;
			private set;
		}

		public string RightString
		{
			get;
			private set;
		}

		/// <summary>
		/// 以一个Command对象关联本类
		/// </summary>
		/// <param name="mainCommand"></param>
		public JoinEntity(Command mainCommand, IEntity entity, string joinType)
		{
			this._mainCommand = mainCommand;
			this._joinType = joinType;
			this._joinedEntity = entity;
		}

		/// <summary>
		/// 指定要关联查询的实体类属性（内部对应字段）
		/// <example>
		/// <![CDATA[
		/// var q1 = Command.From(a)
		///             .InnerJoin(b).On(a.ID,b.ID)
		///             .Select(a.ID,a.Name,b.Name)
		///          .END;
		/// //感谢网友 Tony 扩展了下面的使用方式         
		/// var q2 =  Command.From(a)
		///              .LeftJoin(b).On(a.ID,b.ID, a.Name,b.Name)
		///              .Select(a.ID,a.Name,b.OtherInfo)
		///          .END;
		/// ]]>
		/// </example>
		/// </summary>
		/// <param name="fields">主实体类的关联的属性与从实体关联的属性，必须成对出现</param>
		/// <returns></returns>
		public Command On(params object[] fields)
		{
			if(fields.Length > 0)
			{
				if(fields.Length % 2 > 0)
				{
					throw new Exception("参数个数应为偶数！");
				}
				int count = fields.Length;
				TableNameField tnfRight = this._mainCommand.fieldStack.Pop();
				TableNameField tnfLeft = this._mainCommand.fieldStack.Pop();
				LeftString = this._mainCommand.GetCommandFieldName(tnfLeft);
				RightString = this._mainCommand.GetCommandFieldName(tnfRight);
				this.JoinedString = string.Format("\r\n{0} [{1}] {2}  ON {3} ={4} ", _joinType, _joinedEntity.GetMappingName(), this._mainCommand.GetTableAliases(_joinedEntity), LeftString, RightString);
				this._mainCommand.CommandString += this.JoinedString;
				for(int i = 0; i < (count - 2) / 2; i++)
				{
					TableNameField tnf1 = this._mainCommand.fieldStack.Pop();
					TableNameField tnf2 = this._mainCommand.fieldStack.Pop();
					string tnf1String = this._mainCommand.GetCommandFieldName(tnf1);
					string tnf2String = this._mainCommand.GetCommandFieldName(tnf2);
					this._mainCommand.CommandString += string.Format(" AND {0} = {1} ", tnf1String, tnf2String);
				}
			}
			return this._mainCommand;
		}

		/// <summary>
		/// （Command内部使用）添加要关联的字段名
		/// </summary>
		/// <param name="fieldName"></param>
		public void AddJoinFieldName(string fieldName)
		{
			if(string.IsNullOrEmpty(this.LeftString))
			{
				this.LeftString = fieldName;
			}
			else if(string.IsNullOrEmpty(this.RightString))
			{
				this.RightString = fieldName;
			}
		}
	}
}